package com.dragon.backstage.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dragon.backstage.convert.UserOperateLogConvert;
import com.dragon.backstage.domain.excel.UserOperateLogExportExcel;
import com.dragon.backstage.domain.param.userOperateLog.UserOperateLogParam;
import com.dragon.backstage.domain.vo.userOperateLog.UserOperateLogDetailVo;
import com.dragon.backstage.domain.vo.userOperateLog.UserOperateLogVo;
import com.dragon.backstage.service.UserOperateLogService;
import com.dragon.common.domain.vo.PaginationVo;
import com.dragon.common.utils.AjaxResult;
import com.dragon.common.utils.time.LocalDateUtils;
import com.dragon.interfaces.domain.request.userOperateLog.UserOperateLogRequest;
import com.dragon.interfaces.entity.UserOperateLog;
import com.dragon.interfaces.mapper.UserOperateLogMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 操作日志记录 服务实现类
 * </p>
 *
 * @author dragon
 * @since 2024-08-01 18:08:50
 */
@Slf4j
@Service
public class UserOperateLogServiceImpl extends ServiceImpl<UserOperateLogMapper, UserOperateLog> implements UserOperateLogService {

    @Resource
    private UserOperateLogMapper userOperateLogMapper;


    /**
     * 用户操作日志列表
     *
     * @param userOperateLogParam 查询参数
     * @return 用户操作日志列表
     */
    @Override
    public AjaxResult<PaginationVo<UserOperateLogVo>> userOperateLogList(UserOperateLogParam userOperateLogParam) {
        UserOperateLogRequest userOperateLogRequest = UserOperateLogConvert.toUserOperateLogRequest(userOperateLogParam);

        List<UserOperateLogVo> userOperateLogVos = new ArrayList<>(16);

        List<UserOperateLog> userOperateLogList = userOperateLogMapper.userOperateLogList(userOperateLogRequest);
        Integer total = userOperateLogMapper.userOperateLogCount(userOperateLogRequest);

        if (CollectionUtils.isNotEmpty(userOperateLogList)) {
            userOperateLogVos = userOperateLogList.stream().map(UserOperateLogConvert::toUserOperateLogVo).collect(Collectors.toList());
        }

        return AjaxResult.succeedWith(PaginationVo
            .<UserOperateLogVo>builder()
            .total(total)
            .rows(userOperateLogVos)
            .build()
        );
    }

    /**
     * 用户操作日志详情
     *
     * @param operateId 用户操作日志ID
     * @return 用户操作日志详情
     */
    @Override
    public AjaxResult<UserOperateLogDetailVo> userOperateLogDetail(Long operateId) {
        if (Objects.isNull(operateId)) {
            return AjaxResult.failed("用户操作日志ID不能为空");
        }

        UserOperateLog userOperateLog = userOperateLogMapper.selectById(operateId);
        if (Objects.isNull(userOperateLog)) {
            return AjaxResult.failed("用户操作日志不存在");
        }

        return AjaxResult.succeedWith(UserOperateLogConvert.toUserOperateLogDetailVo(userOperateLog));
    }

    /**
     * 删除用户操作日志
     *
     * @param operateIds 用户操作日志ID
     * @return 删除结果
     */
    @Override
    public AjaxResult<Void> deleteUserOperateLog(Long[] operateIds) {
        if (Objects.isNull(operateIds) || operateIds.length < 1) {
            return AjaxResult.failed("用户操作日志ID不能为空");
        }

        List<Long> operateIdList = Arrays.asList(operateIds);
        Long logNum = userOperateLogMapper.selectCount(new QueryWrapper<UserOperateLog>()
            .in(UserOperateLog.OPERATE_ID, operateIdList)
        );
        if (logNum < 1) {
            return AjaxResult.failed("用户操作日志不存在");
        }

        boolean flag = userOperateLogMapper.deleteByIds(operateIdList) > 0;
        if (!flag) {
            return AjaxResult.failed("删除用户操作日志失败");
        }

        return AjaxResult.succeed();
    }

    /**
     * 导出用户操作日志
     *
     * @param response            响应
     * @param userOperateLogParam 查询参数
     */
    @Override
    public void exportUserOperateLog(HttpServletResponse response, UserOperateLogParam userOperateLogParam) throws IOException {
        userOperateLogParam.setPageNum(1);
        userOperateLogParam.setPageSize(Integer.MAX_VALUE);

        UserOperateLogRequest userOperateLogRequest = UserOperateLogConvert.toUserOperateLogRequest(userOperateLogParam);

        List<UserOperateLog> userOperateLogList = userOperateLogMapper.userOperateLogList(userOperateLogRequest);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("用户操作日志_" + LocalDateUtils.getUnsignedLocalDateTimeStr(), StandardCharsets.UTF_8).replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        List<UserOperateLogExportExcel> userOperateLogExportExcels = userOperateLogList.stream().map(UserOperateLogConvert::toUserOperateLogExportExcel).collect(Collectors.toList());

        EasyExcel.write(response.getOutputStream(), UserOperateLogExportExcel.class).sheet("用户操作日志").doWrite(userOperateLogExportExcels);
    }

    /**
     * 清空用户操作日志
     *
     * @return 清空结果
     */
    @Override
    public AjaxResult<Void> cleanUserOperateLog() {
        userOperateLogMapper.cleanUserOperateLog();

        return AjaxResult.succeed();
    }

}
